#ifndef MYSTL_ALLOCATOR_H
#define MYSTL_ALLOCATOR_H
//首先这个类实现的是一个空间的分配

#include "construct.h"
#include "util.h"

namespace mystl
{
//模板类
template <class T>
class allocator
{
public:
    typedef T value_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
public:
    //分配空间的函数
    static T* allocate();
    static T* allocate(size_type n);
    //释放空间的函数
    static void deallocate(T* ptr);
    static void deallocate(T* ptr,size_type n);
    //用来将已经分配好空间的内存，创建对象
    static void construct(T* ptr);
    static void construct(T* ptr,const T& value);
    static void construct(T* ptr,T&& value);
    //还是没有搞太懂
    template <class... Args>
    static void construct(T* ptr, Args&& ...args);

    //表示将新建的空间给释放掉
    static void destroy(T* ptr);
    static void destroy(T* first, T* last);



};
//首先实现这个allocate，这个函数实现的是一个内存的分配，并且呢，使用了static_cast，将分配的内存的指针转为了模板的类型
//注意的是这个通过使用::operator并没有生成对象，只是开辟了一块空间
template <class T>
T* allocator<T>::allocate()
{
    std::cout<< "1" <<std::endl;
    return static_cast<T*>(::operator new(sizeof(T))); 
}

template <class T>
T* allocator<T>::allocate(size_type n)
{
    if(n==0)
    {
        return nullptr;
    }
    return static_cast<T*>(::operator new(n * sizeof(T)));
}

//内存的释放，把上面开辟的那块空间给释放掉了
template <class T>
void allocator<T>::deallocate(T* ptr)
{
    std::cout<< "3" <<std::endl;
    if(ptr == nullptr)
        return;
    ::operator delete(ptr);
}

template <class T>
void allocator<T>::deallocate(T* ptr,size_type)
{
    std::cout<< "4" <<std::endl;
    if(ptr == nullptr)
    {
        return ;
    }
    ::operator delete(ptr);
}


//在已经分配的内存上  创建ty类型
template <class T>
void allocator<T>::construct(T* ptr)
{
    std::cout<< "5" <<std::endl;
    mystl::construct(ptr);
}

//在已经分配的内存上，创建TY类型的对象，并用value来进行赋值操作
template <class T>
void allocator<T>::construct(T* ptr,const T& value)
{
    std::cout<< "6" <<std::endl;
    mystl::construct(ptr, value);
}

//在已经分配的内存上，创建TY类型的对象，并用value来进行赋值操作,注意的是将其转为了右值引用
template <class T>
void allocator<T>::construct(T* ptr,T&& vaule)
{
    std::cout<< "7" <<std::endl;
    mystl::construct(ptr,mystl::move(vaule));
}

//使用了forward
template<class T>
template<class ...Args>
void allocator<T>::construct(T* ptr, Args&& ...args)
{

    std::cout<< "8" <<std::endl;
    mystl::construct(ptr,mystl::forward(args)...);
}


//调用析构函数
template <class T>
void allocator<T>::destroy(T* ptr)
{    
    std::cout<< "10" <<std::endl;
    mystl::destroy(ptr);

}



template <class T>
void allocator<T>::destroy(T* first,T* last)
{
    std::cout<< "11" <<std::endl;
    mystl::destroy(first, last);
}






} // namespace mystl
#endif // !MYSTL_ALLOCATOR_H
